home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
src
/
haeberli
/
libgutil
/
sgiobj.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
11KB
|
466 lines
/*
* Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
/*
* sgiobj -
* A simple object format.
*
* Paul Haeberli - 1990
*/
#include "stdio.h"
#include "gl.h"
#include "device.h"
#include "sgiobj.h"
#include "spin.h"
#include "resource.h"
static vertprint();
sgiobj *freesgiobj(obj)
sgiobj *obj;
{
if(obj->data)
free(obj->data);
free(obj);
}
sgiobj *newquadobj(nquads)
int nquads;
{
sgiobj *obj;
obj = (sgiobj *)mymalloc(sizeof(sgiobj));
obj->next = 0;
obj->objtype = OBJ_QUADLIST;
obj->nlongs = PNTLONGS*4*nquads;
obj->data = (long *)mymalloc(obj->nlongs*sizeof(long));
obj->xnlongs = 0;
obj->xdata = 0;
return obj;
}
sgiobj *newtriobj(ntri)
int ntri;
{
sgiobj *obj;
obj = (sgiobj *)mymalloc(sizeof(sgiobj));
obj->next = 0;
obj->objtype = OBJ_TRILIST;
obj->nlongs = PNTLONGS*3*ntri;
obj->data = (long *)mymalloc(obj->nlongs*sizeof(long));
obj->xnlongs = 0;
obj->xdata = 0;
return obj;
}
sgiobj *newtmeshobj(nlongs)
int nlongs;
{
sgiobj *obj;
obj = (sgiobj *)mymalloc(sizeof(sgiobj));
obj->next = 0;
obj->objtype = OBJ_TRIMESH;
obj->nlongs = nlongs;
obj->data = (long *)mymalloc(obj->nlongs*sizeof(long));
obj->xnlongs = 0;
obj->xdata = 0;
return obj;
}
sgiobj *clonesgiobj(obj)
sgiobj *obj;
{
sgiobj *cobj;
int nlongs;
cobj = (sgiobj *)mymalloc(sizeof(sgiobj));
*cobj = *obj;
cobj->data = (long *)mymalloc(cobj->nlongs*sizeof(int));
bcopy(obj->data,cobj->data,cobj->nlongs*sizeof(int));
if(cobj->xnlongs) {
cobj->xdata = (long *)mymalloc(cobj->xnlongs*sizeof(int));
bcopy(obj->xdata,cobj->xdata,cobj->xnlongs*sizeof(int));
}
return cobj;
}
sgiobj *readsgiobj(name)
char *name;
{
FILE *inf;
sgiobj *obj, *head, *tail;
int npoints, colors;
long objtype, plongs, nlongs;
long magic;
int i, ntri, nquads;
inf = res_fopen(name,"r");
if(!inf) {
fprintf(stderr,"readsgiobj: can't open input file %s\n",name);
exit(1);
}
res_fread(&magic,sizeof(long),1,inf);
if(magic == FASTMAGIC) {
res_fread(&npoints,sizeof(long),1,inf);
res_fread(&colors,sizeof(long),1,inf);
nquads = npoints/4;
if(colors) {
fprintf(stderr,"readsgiobj: can't read nonormal spin objects\n");
exit(1);
} else
obj = newquadobj(nquads);
bzero(obj->data,obj->nlongs*sizeof(long));
for(i=0; i<npoints; i++) {
res_fread(obj->data+(PNTLONGS*i)+OFFSET_NORMAL,3*sizeof(long),1,inf);
res_fread(obj->data+(PNTLONGS*i)+OFFSET_POINT,3*sizeof(long),1,inf);
bcopy(obj->data+(PNTLONGS*i)+OFFSET_POINT,
obj->data+(PNTLONGS*i)+OFFSET_UVS,3*sizeof(long),1,inf);
}
res_fclose(inf);
return obj;
}
if(magic == SOMAGIC) {
head = 0;
while(1) {
res_fread(&objtype,sizeof(long),1,inf);
if(objtype == OBJ_END)
break;
res_fread(&nlongs,sizeof(long),1,inf);
switch(objtype) {
case OBJ_QUADLIST:
nquads = (nlongs/PNTLONGS)/4;
obj = newquadobj(nquads);
res_fread(obj->data,nlongs*sizeof(long),1,inf);
break;
case OBJ_TRILIST:
ntri = (nlongs/PNTLONGS)/3;
obj = newtriobj(ntri);
res_fread(obj->data,nlongs*sizeof(long),1,inf);
break;
case OBJ_TRIMESH:
obj = newtmeshobj(nlongs);
res_fread(obj->data,nlongs*sizeof(long),1,inf);
break;
default:
fprintf(stderr,"readsgiobj: bad obj type %d\n",objtype);
exit(1);
break;
}
if(head == 0) {
head = tail = obj;
} else {
tail->next = obj;
tail = obj;
}
}
res_fclose(inf);
return head;
}
fprintf(stderr,"readsgiobj: bad magic %d in object file\n",magic);
exit(1);
}
writesgiobj(name,obj)
char *name;
sgiobj *obj;
{
FILE *outf;
long endtype;
int magic;
outf = fopen(name,"w");
if(!outf) {
fprintf(stderr,"writesgiobj: can't open input file %s\n",name);
exit(1);
}
magic = SOMAGIC;
fwrite(&magic,sizeof(long),1,outf);
while(obj) {
fwrite(&obj->objtype,sizeof(long),1,outf);
fwrite(&obj->nlongs,sizeof(long),1,outf);
fwrite(obj->data,obj->nlongs*sizeof(long),1,outf);
obj = obj->next;
}
endtype = OBJ_END;
fwrite(&endtype,sizeof(long),1,outf);
fclose(outf);
}
applytoverts(obj,func)
sgiobj *obj;
int (*func)();
{
long npolys, nverts;
long *data;
char *vertdata, *avert;
data = obj->data;
if(obj->objtype == OBJ_QUADLIST) {
npolys = (obj->nlongs/PNTLONGS)/4;
while(npolys--) {
func(&data[(PNTLONGS*0)]);
func(&data[(PNTLONGS*1)]);
func(&data[(PNTLONGS*2)]);
func(&data[(PNTLONGS*3)]);
data += PNTLONGS*4;
}
} else if(obj->objtype == OBJ_TRILIST) {
npolys = (obj->nlongs/PNTLONGS)/3;
while(npolys--) {
func(&data[(PNTLONGS*0)]);
func(&data[(PNTLONGS*1)]);
func(&data[(PNTLONGS*2)]);
data += PNTLONGS*3;
}
} else if(obj->objtype == OBJ_TRIMESH) {
nverts = (*data++)/PNTLONGS;
while(nverts--) {
func(data);
data += PNTLONGS;
}
} else {
fprintf(stderr,"applytoverts: bad object type %d\n",obj->objtype);
exit(1);
}
}
/*
* count triangles in an sgi object.
*
*
*/
static int tricount;
static int pcount()
{
tricount++;
}
objpolys(obj)
sgiobj *obj;
{
tricount=0;
applytotris(obj,pcount);
return tricount;
}
applytomeshtris(obj,trifunc)
sgiobj *obj;
int (*trifunc)();
{
long *data;
char *vertdata, *avert;
int vertlongs, nverts;
if(obj->objtype != OBJ_TRIMESH) {
fprintf(stderr,"applytomeshtris: object type is not a tmesh\n");
exit(1);
}
data = obj->data;
vertlongs = *data++;
vertdata = (char *)data;
data += vertlongs;
mesh_callback(trifunc);
while(1) {
switch(*data++) {
case OP_BGNTMESH:
mesh_bgntmesh();
break;
case OP_SWAPTMESH:
mesh_swaptmesh();
break;
case OP_ENDBGNTMESH:
mesh_endtmesh();
mesh_bgntmesh();
break;
case OP_ENDTMESH:
mesh_endtmesh();
return;
default:
fprintf(stderr,"applytomeshtris: bad tmesh op %d\n",*data);
exit(1);
}
nverts = *data++;
while(nverts--) {
avert = vertdata + *data++;
mesh_vert(avert);
}
}
}
static int (*usertrifunc)();
static mymeshtrifunc(data)
long *data[3];
{
(usertrifunc)(data[0],data[1],data[2]);
}
applytotris(obj,func)
sgiobj *obj;
int (*func)();
{
long npolys;
long *data;
char *vertdata, *avert;
int nverts;
data = obj->data;
if(obj->objtype == OBJ_QUADLIST) {
npolys = (obj->nlongs/PNTLONGS)/4;
while(npolys--) {
func(&data[(PNTLONGS*0)],
&data[(PNTLONGS*1)],
&data[(PNTLONGS*3)]);
func(&data[(PNTLONGS*2)],
&data[(PNTLONGS*3)],
&data[(PNTLONGS*1)]);
data += PNTLONGS*4;
}
} else if(obj->objtype == OBJ_TRILIST) {
npolys = (obj->nlongs/PNTLONGS)/3;
while(npolys--) {
func(&data[(PNTLONGS*0)],
&data[(PNTLONGS*1)],
&data[(PNTLONGS*2)]);
data += PNTLONGS*3;
}
} else if(obj->objtype == OBJ_TRIMESH) {
usertrifunc = func;
applytomeshtris(obj,mymeshtrifunc);
} else {
fprintf(stderr,"applytotris: bad object type %d\n",obj->objtype);
exit(1);
}
}
sgiobj *catsgiobj(obj1,obj2)
sgiobj *obj1, *obj2;
{
sgiobj *obj;
long *data;
long npolys1, npolys2;
if(obj1->objtype != obj2->objtype) {
fprintf(stderr,"catsgiobj: both objects must have the same type\n");
exit(1);
}
if(obj1->objtype == OBJ_QUADLIST) {
npolys1 = (obj1->nlongs/PNTLONGS)/4;
npolys2 = (obj2->nlongs/PNTLONGS)/4;
obj = newquadobj(npolys1+npolys2);
data = obj->data;
bcopy(obj1->data,data,obj1->nlongs*sizeof(long));
data += obj1->nlongs;
bcopy(obj2->data,data,obj2->nlongs*sizeof(long));
return obj;
} else if(obj1->objtype == OBJ_TRILIST) {
npolys1 = (obj1->nlongs/PNTLONGS)/3;
npolys2 = (obj2->nlongs/PNTLONGS)/3;
obj = newtriobj(npolys1+npolys2);
data = obj->data;
bcopy(obj1->data,data,obj1->nlongs*sizeof(long));
data += obj1->nlongs;
bcopy(obj2->data,data,obj2->nlongs*sizeof(long));
return obj;
} else if(obj->objtype == OBJ_TRIMESH) {
fprintf(stderr,"catsgiobj: tmesh not implemented\n");
exit(1);
} else {
fprintf(stderr,"catsgiobj: bad object type %d\n",obj->objtype);
exit(1);
}
}
printsgiobj(obj,how)
sgiobj *obj;
int how;
{
long npolys;
long *data;
char *vertdata, *avert;
int vertlongs, nverts;
data = obj->data;
if(obj->objtype == OBJ_QUADLIST) {
npolys = (obj->nlongs/PNTLONGS)/4;
while(npolys--) {
printf("QUAD:\n");
vertprint(&data[PNTLONGS*0]);
vertprint(&data[PNTLONGS*1]);
vertprint(&data[PNTLONGS*2]);
vertprint(&data[PNTLONGS*3]);
data += PNTLONGS*4;
}
} else if(obj->objtype == OBJ_TRILIST) {
npolys = (obj->nlongs/PNTLONGS)/3;
while(npolys--) {
printf("TRI:\n");
vertprint(&data[PNTLONGS*0]);
vertprint(&data[PNTLONGS*1]);
vertprint(&data[PNTLONGS*2]);
data += PNTLONGS*3;
}
} else if(obj->objtype == OBJ_TRIMESH) {
vertlongs = *data++;
printf("vertlongs is %d\n",vertlongs);
vertdata = (char *)data;
data += vertlongs;
printf("TMESH:\n");
while(1) {
switch(*data++) {
case OP_BGNTMESH:
printf("bgntmesh\n");
break;
case OP_SWAPTMESH:
printf("swaptmesh\n");
break;
case OP_ENDBGNTMESH:
printf("endbgntmesh\n");
break;
case OP_ENDTMESH:
printf("endtmesh\n");
return;
default:
fprintf(stderr,"printsgiobj: bad tmesh op %d\n",*data);
exit(1);
}
nverts = *data++;
while(nverts--) {
avert = vertdata + *data++;
vertprint(avert);
}
}
} else {
fprintf(stderr,"printsgiobj: bad object type %d\n",obj->objtype);
exit(1);
}
}
static vertprint(fptr)
float *fptr;
{
printf("pos: %f %f %f\n",
fptr[OFFSET_POINT+0],fptr[OFFSET_POINT+1],fptr[OFFSET_POINT+2]);
printf("norm: %f %f %f\n",
fptr[OFFSET_NORMAL+0],fptr[OFFSET_NORMAL+1],fptr[OFFSET_NORMAL+2]);
printf("uvs: %f %f %f\n",
fptr[OFFSET_UVS+0],fptr[OFFSET_UVS+1],fptr[OFFSET_UVS+2]);
printf("\n");
}